<?php

namespace App\Kuafu\WaiMai\Service;

use App\Kuafu\Audit\Enum\AuditEventCodeEnum;
use App\Kuafu\Common\Service\CommonService;
use App\Kuafu\Common\Service\InformationPushService;
use App\Kuafu\CouponExt\Channel\MeiTuan\MeiTuanBase;
use App\Kuafu\Pay\Model\PayStreamModel;
use App\Kuafu\Shop\Enum\CodeEnum;
use App\Kuafu\Shop\Enum\ShopCodeEnum;
use App\Kuafu\Shop\Exceptions\ShopException;
use App\Kuafu\Shop\Model\Shop;
use App\Kuafu\Shop\Model\ShopPaymentsModel;
use App\Kuafu\Shop\Service\ShopInvoiceService;
use App\Kuafu\Shop\Service\ShopService;
use App\Kuafu\Shop\Validate\ShopInvoiceValidate;
use App\Kuafu\User\Service\UserRoleService;
use App\Kuafu\WaiMai\Channel\BaseWaiMai;
use App\Kuafu\WaiMai\Enum\WaiMaiCacheEnum;
use App\Kuafu\WaiMai\Enum\WaiMaiCodeEnum;
use App\Kuafu\WaiMai\Enum\WaiMaiDBEnum;
use App\Kuafu\WaiMai\Exceptions\WaiMaiException;
use App\Kuafu\WaiMai\Model\WaiMaiShopMappingModel;
use App\Remote\Tiger\Appraise\AppraiseRemote;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;


class WaiMaiShopService
{
    private int  $shopId;
    private Shop $shop;

    /**
     * @param int|Shop $shop
     */
    public function __construct($shop)
    {
        if ($shop instanceof Shop) {
            $this->shop   = $shop;
            $this->shopId = $shop->id;
        } else {
            $this->shopId = $shop;
            $this->shop   = ShopService::getShopInfo($this->shopId);
        }
    }

    /**
     * 绑定Url
     * @param int $sourceType
     * @return string
     */
    public function bindUrl(int $sourceType): string
    {
        if ($sourceType != WaiMaiDBEnum::SOURCE_TYPE_MT_TG) {
            return '';
        }

        return (new MeiTuanBase($this->shop, false))->storeMap(MeiTuanBase::BUSINESS_ID_1);
    }

    /**
     * 解绑Url
     * @param int $sourceType
     * @return string
     */
    public function unbindUrl(int $sourceType): string
    {
        if ($sourceType != WaiMaiDBEnum::SOURCE_TYPE_MT_TG) {
            return '';
        }

        return (new MeiTuanBase($this->shop, true, false))->unstoreMap(MeiTuanBase::BUSINESS_ID_1);
    }

    /**
     * 美团团购回调绑定
     * @param string $thirdShopId
     * @param string $thirdShopName
     * @param int $businessId
     * @param string $appAuthToken
     * @throws WaiMaiException
     */
    public function bindMTCallback(
        string $thirdShopId,
        string $thirdShopName,
        int $businessId,
        string $appAuthToken
    ): void {
        // 团购券配置存储
        if ($businessId == MeiTuanBase::BUSINESS_ID_1) {
            $sourceType = WaiMaiDBEnum::SOURCE_TYPE_MT_TG;
        } else {
            throw new WaiMaiException(WaiMaiCodeEnum::ERR_SOURCE_TYPE);
        }

        // 解除和其他店铺的映射
        $currentBind = self::getMappingCache($this->shopId, $sourceType);
        if ($currentBind) {
            WaiMaiShopMappingModel::delData($this->shopId, $currentBind->sourceType);
            Cache::forget(WaiMaiCacheEnum::getShopMapping($this->shopId, $currentBind->sourceType));
        }

        // 店铺映射
        WaiMaiShopMappingModel::addData($sourceType, $this->shopId, $thirdShopId, $thirdShopName, $appAuthToken);

        Cache::forget(WaiMaiCacheEnum::getShopMapping($this->shopId, $sourceType));
    }

    /**
     * 美团团购回调解绑
     * @param int $businessId
     * @throws WaiMaiException
     */
    public function unbindMtCallback(int $businessId): void
    {
        if ($businessId == MeiTuanBase::BUSINESS_ID_1) {
            $sourceType = WaiMaiDBEnum::SOURCE_TYPE_MT_TG;
        } else {
            throw new WaiMaiException(WaiMaiCodeEnum::ERR_SOURCE_TYPE);
        }

        WaiMaiShopMappingModel::delData($this->shopId, $sourceType);

        Cache::forget(WaiMaiCacheEnum::getShopMapping($this->shopId, $sourceType));
    }

    /**
     * 获取店铺的绑定信息
     * @param int $shopId
     * @param int $sourceType
     * @return mixed
     */
    public static function getMappingCache(int $shopId, int $sourceType)
    {
        return Cache::remember(WaiMaiCacheEnum::getShopMapping($shopId, $sourceType), 300,
            function () use ($shopId, $sourceType) {
                return WaiMaiShopMappingModel::getDataByShopId($shopId, $sourceType);
            });
    }

    /**
     * 通过thirdShopId获取shopId
     * @param string $thirdShopId
     * @param int $sourceType
     * @return int
     */
    public static function getThirdMappingCache(string $thirdShopId, int $sourceType): int
    {
        return Cache::remember(WaiMaiCacheEnum::getThirdShopMapping($thirdShopId, $sourceType), 120,
            function () use ($thirdShopId, $sourceType) {
                return (int)WaiMaiShopMappingModel::query()->where('thirdShopId', $thirdShopId)
                                                  ->where('sourceType', $sourceType)
                                                  ->value('shopId');
            });
    }

    /**
     * 绑定外卖店铺
     * @param string $thirdShopId
     * @param int $sourceType
     * @throws ShopException
     * @throws WaiMaiException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function bindWaiMai(string $thirdShopId, int $sourceType): void
    {
        if (!in_array($sourceType, [WaiMaiDBEnum::SOURCE_TYPE_MT_WM, WaiMaiDBEnum::SOURCE_TYPE_ELM])) {
            throw new WaiMaiException(WaiMaiCodeEnum::ERR_SOURCE_TYPE);
        }

        $shop = ShopService::getShopInfo($this->shopId);
        if (!$shop) {
            throw new ShopException(ShopCodeEnum::ERR_SHOP_ID_NO_EXIST);
        }

        // 检查thirdShopId是否已被绑定
        $checkShopId = WaiMaiShopMappingModel::getShopIdByThirdShopId($thirdShopId, $sourceType);
        if ($checkShopId) {
            throw new WaiMaiException(WaiMaiCodeEnum::ERR_THIRD_SHOP_ID_EXISTS, "该三方门店id已被店铺ID:{$checkShopId}绑定");
        }

        // 外卖平台的店铺信息
        $waiMaiShop = BaseWaiMai::getIns($sourceType, $shop->id, $thirdShopId)->getShop();
        if (!$waiMaiShop['status']) {
            throw new WaiMaiException(WaiMaiCodeEnum::ERR_SHOP_ID_NOT_BIND, $waiMaiShop['msg']);
        }
        $shopName = $waiMaiShop['data']['name'] ?? '';
        if (!$shopName) {
            throw new WaiMaiException(WaiMaiCodeEnum::ERR_WM_SHOP_NAME_EMPTY);
        }

        WaiMaiShopMappingModel::addData(
            $sourceType,
            $this->shopId,
            $thirdShopId,
            $shopName
        );

        $userIds = UserRoleService::getShopManageList(
                config('merchant.manager_role_id'),
                [$this->shopId]
            )['lists'] ?? [];

        InformationPushService::push(
            (($sourceType == WaiMaiDBEnum::SOURCE_TYPE_MT_WM) ? InformationPushService::MT_OPEN_PUSH : InformationPushService::ELM_OPEN_PUSH),
            array_column($userIds, 'userId'),
            $shop
        );

        Cache::forget(WaiMaiCacheEnum::getShopMapping($this->shopId, $sourceType));
        //日常运营阶段 饿了么外卖上线&美团外卖上线「需推送」 点评团购上线&抖音团购上线「需推送」
        AppraiseRemote::waimaiNotify($this->shopId, $sourceType, $thirdShopId);
    }

    /**
     * 解绑外卖店铺
     * @param int $sourceType
     * @throws WaiMaiException
     */
    public function unbindWaiMai(int $sourceType): void
    {
        if (!in_array($sourceType, [
            WaiMaiDBEnum::SOURCE_TYPE_MT_WM,
            WaiMaiDBEnum::SOURCE_TYPE_ELM,
            WaiMaiDBEnum::SOURCE_TYPE_FUYOU,
            WaiMaiDBEnum::SOURCE_TYPE_INVOICE
        ])) {
            throw new WaiMaiException(WaiMaiCodeEnum::ERR_SOURCE_TYPE);
        }

        // 门店档案「富友支付」「开票信息」增加解绑操作
        if (in_array($sourceType, [
            WaiMaiDBEnum::SOURCE_TYPE_FUYOU,
            WaiMaiDBEnum::SOURCE_TYPE_INVOICE
        ])) {
            switch ($sourceType) {
                case WaiMaiDBEnum::SOURCE_TYPE_FUYOU:
                    $shopPayments = ShopPaymentsModel::query()
                                                     ->where('shopId', $this->shopId)
                                                     ->where('payChannel', PayStreamModel::PAY_CHANNEL_FY)
                                                     ->first();
                    if ($shopPayments) {
                        $shopPayments->isDeleted = 1;
                        $shopPayments->save();

                        CommonService::fsLogOperate(
                            AuditEventCodeEnum::EVENT_TYPE_10005,
                            $shopPayments->toArray(),
                            [
                                'payChannel' => '',
                                'payConfig'  => '',
                            ],
                            'kf_shop_payments',
                            ['shopInfo' => Shop::query()->where('id', $this->shopId)->first()->only(['id', 'name'])]
                        );
                    }
                    break;
                case WaiMaiDBEnum::SOURCE_TYPE_INVOICE:
                    $getShopInvoiceInfo = ShopInvoiceService::getShopInvoiceInfo($this->shopId);
                    if ($getShopInvoiceInfo) {
                        ShopService::updateShopInfo(['id' => $this->shopId],
                            [
                                'invoice' => json_encode(
                                    [
                                        'selected'                    => CodeEnum::SHOP_INVOICE_CODE_0,
                                        CodeEnum::SHOP_INVOICE_CODE_0 => []
                                    ]
                                )
                            ]);
                    }
                    break;
            }
            return;
        }
        WaiMaiShopMappingModel::delData($this->shopId, $sourceType);

        Cache::forget(WaiMaiCacheEnum::getShopMapping($this->shopId, $sourceType));
    }
}
